package captor.lib.xalan.extensions;

import java.util.List;

import org.apache.xalan.extensions.XSLProcessorContext;
import org.apache.xalan.templates.ElemExtensionCall;
import org.apache.xalan.transformer.TransformerImpl;
import org.apache.xml.dtm.ref.DTMNodeProxy;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import captor.crosscuttingdomainsystem.CrosscuttingDomain;
import captor.modelsystem.Model;
import captor.projectsystem.ProjectSystem;

/**
 * 
 * Captor Extension. 
 * 
 * <p>
 * Xalan XSLT Captor extension element for AOP patterns.
 * </p>
 * 
 * @author Carlos Alberto
 *
 */

public class CaptorExtension
{
	
	//Return the concrete value for the pointcut defined by 'refName' attribute 
	public String abstractpointcut(XSLProcessorContext context,
			ElemExtensionCall elem)
	{				
		StringBuffer result = new StringBuffer("");				
		try
		{												
			Element contextNode = (Element) context.getContextNode();
			String refName = elem.getAttribute("refname");
			
			if ((refName == null) || (refName.equals("")))
				return "";
			
			//Search for all 'pointcutatt' elements in the source document
			Document documentRoot = (Document) ((DTMNodeProxy)contextNode).getDocumentElement();
			NodeList nodes = (NodeList) documentRoot.getElementsByTagName("pointcutatt");
			
			//Find the correspondent nodes by 'refName' attribute  
			for (int i=0; i < nodes.getLength(); i++) {
	            Element pointcutElement = (Element) nodes.item(i);
	            String pointcutRefName = pointcutElement.getAttribute("refname");
	            if (refName.equals(pointcutRefName)){
	            	//Append the concrete value 
	            	NodeList concreteNodes =  (NodeList) pointcutElement.getElementsByTagName("concretevalue");
	            	Element concreteElement = (Element) concreteNodes.item(0);
	            	String concreteValue = concreteElement.getFirstChild().getNodeValue();
	            	if (!result.toString().equals(""))
	            		result = result.append("\n");
	            	result = result.append(concreteValue);
	            }
	        }
		}
		catch (Exception e)
		{
			System.out.println("Exception: " + e.getMessage());
			e.printStackTrace();
		}
		return result.toString();
	}
	
	public void extensionset(XSLProcessorContext context,
			ElemExtensionCall elem)
	{				
		try
		{					
			String domainName = elem.getAttribute("crosscuttingdomain");
			if (iscrosscuttedby(domainName)){
				TransformerImpl transformer = context.getTransformer();
				transformer.executeChildTemplates(elem, true);
			}
		}
		catch (Exception e)
		{
			System.out.println("Exception: " + e.getMessage());
			e.printStackTrace();
		}
	}
	
	public boolean iscrosscuttedby(String domainName)
	{				
		boolean result = false;		
		try
		{								
			final Model model = ProjectSystem.getModelInstance();
			final List<CrosscuttingDomain> list = model.getProject().getCrosscuttingDomains();		
			
			for (final CrosscuttingDomain crosscuttingDomain : list ){
				if (crosscuttingDomain.getNameDomain().equals(domainName)){
					result = true;
					break;
				}
			}			
		}
		catch (Exception e)
		{
			System.out.println("Exception: " + e.getMessage());
			e.printStackTrace();
		}
		
		return result;
	}
	
}